﻿using System;
using System.IdentityModel.Policy;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc.Filters;
using PortalWeb.Common;
using PortalWeb.Core.IManager;
using Quick.Common.Components;

namespace PortalWeb.Web.Filter
{

    public class CustomAuthorizeAttribute : ActionFilterAttribute
    {
        /// <summary>
        /// 能够访问的角色
        /// </summary>
        public new string Roles { get; set; }

        private string[] RolesArray
        {
            get { return Roles.Split(','); }

        }

        public override async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }
            string controllerName = context.ActionDescriptor.DisplayName;
            string actionName = context.ActionDescriptor.DisplayName;
            string area = string.Empty;
            if (context.RouteData.DataTokens["area"] != null)
            {
                area = context.RouteData.DataTokens["area"].ToString();
            }
            var roles = await GetRoles.GetActionRolesAsync(actionName, controllerName, area);
            if (!string.IsNullOrWhiteSpace(roles))
            {
                this.Roles = roles;
            }
            if (context.HttpContext.User.Identity.IsAuthenticated && Roles != null &&
                RolesArray.Any(context.HttpContext.User.IsInRole))
            {
                //非验证用户直接失败
                await next();
            }
        }



        public class GetRoles
        { 
            public static async Task<string> GetActionRolesAsync(string action, string controller, string area)
            {
                string cachekey = string.Format("RolsCache~/{0}/{1}/{2}", area, controller, action);
                object rolesObject = CacheHelper.Get(cachekey);
                if (rolesObject == null)
                {
                    //todo:以后使用IOC框架取得
                    var sfm = ObjectContainer.Resolve<IFunctionManager>();

                    string actionUrl = string.Format("/{0}/{1}/{2}", area, controller, action).ToLower();
                    var function = await sfm.GetByUrlAsync(actionUrl);

                    string roles = "";
                    if (function != null)
                    {
                        foreach (var role in function.Roles)
                        {
                            roles += role.Name + ",";
                        }
                    }
                    CacheHelper.Insert(cachekey, roles);
                    return roles;
                }
                else
                {
                    return rolesObject as string;
                }
            }

           
        }
    }
}